#include "id_card.h"
#include "rfid_common.h"
#include "rfid_interface.h"
#include <string.h>
#include <stdbool.h>

#if RFID_ITF_ID_CARD_EN

static id_card_decode_t id_card_decode[3] = 
{
	[0] = //512us  /64
	{
		.mdecode.fperiod_num = ID_FPERIOD_NUM(ID_BIT_PERIOD_64),
		.mdecode.hperiod_num = ID_HPERIOD_NUM(ID_BIT_PERIOD_64),
		.mdecode.allow_value = ID_ALLOW_VALUE(ID_BIT_PERIOD_64),
	},
	
	[1] = //256us  /32
	{
		.mdecode.fperiod_num = ID_FPERIOD_NUM(ID_BIT_PERIOD_32),
		.mdecode.hperiod_num = ID_HPERIOD_NUM(ID_BIT_PERIOD_32),
		.mdecode.allow_value = ID_ALLOW_VALUE(ID_BIT_PERIOD_32),
	},
	
	[2] = //128us  /16
	{
		.mdecode.fperiod_num = ID_FPERIOD_NUM(ID_BIT_PERIOD_16),
		.mdecode.hperiod_num = ID_HPERIOD_NUM(ID_BIT_PERIOD_16),
		.mdecode.allow_value = ID_ALLOW_VALUE(ID_BIT_PERIOD_16),
	}
};

static void card_data_decode(id_card_decode_t *decode, bool bit);
static int row_data_even_check(uint8_t *datas);
static int column_data_even_check(uint8_t *datas);
static void data_to_uid(uint8_t *uid, uint8_t *rf_data);

//获取ID卡UID
int id_card_get(uint8_t uid[5])
{
	int ret = -1;
	const uint8_t invalid_uid[5] = {0x00};
	
	for(int i=0; i<(sizeof(id_card_decode) / sizeof(id_card_decode[0])); i++)
	{
		id_card_decode_t *decode = &id_card_decode[i];
		if(decode->recv_done)
		{
			if(row_data_even_check(decode->data) == 0)
			{
				if(column_data_even_check(decode->data) == 0)
				{
					data_to_uid(uid, decode->data);
					if(memcmp(uid, invalid_uid, sizeof(invalid_uid)))
						ret = 0;
				}
			}
			decode->header = 0;
			decode->row_index = 0;
			decode->column_index = 0;
			decode->recv_done = 0;
		}
	}
	return ret;
}

//解析AD数据 在ADC-DMA半中断以及满中断调用
void id_card_data_decode(uint16_t *value, uint16_t len)
{
	for(int i=0; i<(sizeof(id_card_decode) / sizeof(id_card_decode[0])); i++)
	{
		id_card_decode_t *decode = &id_card_decode[i];
		manchester_decode_t *mdecode = &decode->mdecode;
		uint32_t central_value = compute_average_adc_value(value, MIN(decode->mdecode.fperiod_num * ID_CENTRAL_VALUE_REF_NUM, len));//计算电压中心值
		uint32_t index = 0;
		
		while(len)
		{
			if(mdecode->hperiod_cnt == 0)//半周期的开始
			{
				mdecode->level = (value[index ++] >= central_value) ? 0 : 1;//获取半周期电平(反向检测)
				mdecode->hperiod_cnt = 1;
			}
			
			while((mdecode->level == 0 && value[index] >= central_value) || (mdecode->level == 1 && value[index] <= central_value))//计算半周期时间
			{
				index ++;
				mdecode->hperiod_cnt ++;
				if(mdecode->hperiod_cnt >= (decode->mdecode.hperiod_num + decode->mdecode.allow_value))//超出半周期读取
				{
					index -= (decode->mdecode.hperiod_num + decode->mdecode.allow_value) - decode->mdecode.hperiod_num;
					mdecode->hperiod_cnt -= (decode->mdecode.hperiod_num + decode->mdecode.allow_value) - decode->mdecode.hperiod_num;
					break;
				}
				if(index >= len)break ;
			}
			if(index >= len)break ;
			
			if((mdecode->hperiod_cnt >= (decode->mdecode.hperiod_num - decode->mdecode.allow_value))) //检查半周期是否正确
			{
				mdecode->hperiod_cnt = 0;
				mdecode->hp_bit_data <<= 1;
				mdecode->hp_bit_data |= mdecode->level ? 0x01 : 0x00;
				if(mdecode->hp_bit_cnt < 8) mdecode->hp_bit_cnt ++;
				
				if(mdecode->hp_bit_cnt >= 2)//接收到完整的1bit数据
				{
					bool bit = (mdecode->hp_bit_data & 0x02) ? 1 : 0;
					if((mdecode->hp_bit_data & 0x03) != 0x03 && (mdecode->hp_bit_data & 0x03) != 0x00)//检查数据位是否正确
					{
						card_data_decode(decode, bit);
					}
					else //数据位错误
					{
						decode->header = 0;
						mdecode->hp_bit_cnt -= 1;	//继续接收半字节
					}
				}
			}
			else //半周期数据错误,取消数据的解析
			{
				mdecode->hperiod_cnt = 0;
			}
		}
	}
}

static void id_card_decode_reset(id_card_decode_t *decode){
	manchester_decode_t *mdecode = &decode->mdecode;
	
	decode->header = 0;
	decode->recv_done = 0;
	decode->row_index = 0;
	decode->column_index = 0;
	mdecode->hp_bit_cnt = 0;	//继续接收半字节
	mdecode->hperiod_cnt = 0;
	mdecode->hp_bit_data = 0;
	mdecode->level = 0;
}

void id_card_reset(void){
	int i;

	for(i = 0; i < sizeof(id_card_decode)/sizeof(id_card_decode[0]); i++){
		id_card_decode_reset(&id_card_decode[i]);
	}
}

//解析TK4100/EM4200卡类型数据
static void card_data_decode(id_card_decode_t *decode, bool bit)
{
	manchester_decode_t *mdecode = &decode->mdecode;
	
	if(decode->recv_done)return;
	
	if(decode->header < ID_HEADER_BIT_NUM)//头数据接收完成
	{
		if(bit == 1)
		{
			decode->header ++;
			if(decode->header == ID_HEADER_BIT_NUM)
			{
				memset(decode->data, 0, sizeof(decode->data));
				decode->row_index = 0;
				decode->column_index = 0;
			}
			mdecode->hp_bit_cnt -= 2;
		}
		else 
		{
			decode->header = 0;
			mdecode->hp_bit_cnt -= 1;
		}
	}
	else 
	{
		decode->data[decode->column_index] <<= 1;
		decode->data[decode->column_index] |= bit ? 0x01 : 0x00;
		decode->row_index ++;
		
		if(decode->row_index >= ID_DATA_BIT_NUM)
		{
			decode->row_index = 0;
			decode->column_index ++;
		}
		
		if(decode->column_index >= ID_DATA_BUF_LEN)//接收完成
		{
			if(bit != 0)
			{
				decode->header = 0;
				decode->row_index = 0;
				decode->column_index = 0;
			}
			else
			{
				decode->recv_done = 1;
			}
		}
		mdecode->hp_bit_cnt -= 2;//接收下一位数据
	}
}

static int row_data_even_check(uint8_t *datas)
{
	uint8_t i, j;
	uint8_t tmp, even_check;

	for(i = 0; i < 10; i++)
	{
		tmp = datas[i];
		even_check = 0;
		
		for(j = 0; j < 5; j++)
		{
			even_check ^= (tmp & 0x01); //LSB
			tmp >>= 1; //next bit
		}

		if(even_check != 0) //even check error
		{
			return -1;
		}
	}
	
	return 0;
}

static int column_data_even_check(uint8_t *datas)
{
	uint8_t i;
	uint8_t tmp, even_check = 0;

	for(i = 0; i < 11; i++)
	{
		tmp = (datas[i] & 0x1F) >> 1;
		even_check ^= tmp;
	}

	if(even_check != 0)
	{
		return -1;
	}

	return 0;
}

static void data_to_uid(uint8_t *uid, uint8_t *rf_data)
{
	uint8_t i;
	
	for(i = 0; i < 5; i++)
	{
		uid[i] = ((rf_data[(i << 1)] << 3) & 0xF0) + \
					((rf_data[(i << 1) + 1] >> 1) & 0x0F);
	}
}

#endif
